package framework.gui.panels;

import framework.interfaces.Visualization;
import framework.world.CellImpl;
import framework.world.World;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.JLabel;


/**
 * Class that controls the user's view of each cell in the grid in the GUI.
 * Also handles the user's interaction with the cells.
 * 
 * @author Alex Duda
 */

@SuppressWarnings("serial")
public class GridCell extends JLabel implements MouseListener {
	
	private final int CELL_SIZE = 10;
	private final Dimension CELL_DIM = new Dimension(CELL_SIZE,CELL_SIZE);
	
	private int row;
	private int col;
	
	private World world;
	private GridPanel topPanel;
	private Visualization visualizer;
	private CellImpl cell;
	
	/**
	 * Initializes the grid cell with the correct size, color, and border visibility.
	 * @param gridPanel the grid that the gridCell is in
	 * @param framework.world the state of the framework.world when the grid cell is initialized
	 * @param row the row that the cell is in
	 * @param col the column that the cell is in.
	 */
	
	public GridCell(GridPanel gridPanel, World world, int row, int col) {
		this.row = row;
		this.col = col;
		this.world = world;
		
		topPanel = gridPanel;
		
		cell = world.getGrid()[row][col];
		
		visualizer = world.getVisualization();

		addMouseListener(this);
		
		setPreferredSize(CELL_DIM);
		setBackground(visualizer.setCellStyle(cell.getState()));
		setOpaque(true);
		
		updateBorder();
	}
	
	/**
	 * Alters the cell so it matches its default state.
	 */
	
	public void reset() {
		cell = world.getGrid()[row][col];
		
		setBackground(visualizer.setCellStyle(world.getRules().getDefaultState()));
		setOpaque(true);
		
		world.setStateAtRowCol(world.getRules().getDefaultState(), row, col);
	}
	
	/**
	 * Re-paints the cell based on the current state of the framework.world
	 */
	
	public void paintCell(){
		int nextState;	
			
		if(topPanel.getNumStates() == 2){
			nextState =  (world.getLocationState(row, col) + 1) % topPanel.getNumStates();
		}
		else{
			nextState = topPanel.getPaintState();
		}
		
		setBackground(visualizer.setCellStyle(nextState));
		setOpaque(true);
		
		world.setStateAtRowCol(nextState, row, col);
	}

	/**
	 * Re-paints the color of the cell.
	 */
	
	public void updateCell(){
		cell = world.getGrid()[row][col];
		
		setBackground(visualizer.setCellStyle(cell.getState()));
		setOpaque(true);
	}
	
	/**
	 * Re-paints the border of the cell.
	 */
	
	public void updateBorder(){
		if(topPanel.isGridViewable()){
			setBorder(BorderFactory.createLineBorder(Color.GRAY));
		}
		else{
			setBorder(null);
		}
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
	 */
	
	@Override
	public void mouseEntered(MouseEvent arg0) {
		if(topPanel.getMousePressed()){
			paintCell();	
		}
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
	 */
	
	@Override
	public void mousePressed(MouseEvent arg0) {
		topPanel.setMousePressed(true);
		paintCell();
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
	 */
	
	@Override
	public void mouseReleased(MouseEvent arg0) {
		topPanel.setMousePressed(false);
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
	 */
	
	@Override
	public void mouseClicked(MouseEvent e) {
		// Do Nothing
	}

	/* (non-Javadoc)
	 * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
	 */
	
	@Override
	public void mouseExited(MouseEvent e) {
		//Do nothing
	}

}
